-- Type Derivations --

	-- Replaces type names with real types
TypeName.Derive (.tree => .tree1) :-
	TypeName.Declarations (.tree,) (.tree => .tree1) #

TypeName.Declarations .scopes (.decls, .remains => .decls1, .remains1) :-
	TypeName.Declaration .scopes (.decls => .decls1),
	TypeName.Declarations .scopes (.remains => .remains1) #
TypeName.Declarations . ($ => $) #

TypeName.Declaration .scopes (TYPEDEF .type .name => TYPEDEF .type1 .name) :-
	TypeName.Type .scopes (.type => .type1) #
TypeName.Declaration .scopes (VARDEF .type .name => VARDEF .type1 .name) :-
	TypeName.Type .scopes (.type => .type1) #
TypeName.Declaration .scopes (VARDEFVALUE .type .name .value =>
	VARDEFVALUE .type1 .name .value) :-
	TypeName.Type .scopes (.type => .type1) #

TypeName.Type . (VOID => VOID) #
TypeName.Type . (INTTYPE .i => INTTYPE .i) #
TypeName.Type .scopes (PTR .i => PTR .i1) :-
	TypeName.Type .scopes (.i => .i1) #
TypeName.Type .scopes (ARRAY .size .i => ARRAY .size .i1) :-
	TypeName.Type .scopes (.i => .i1) #
TypeName.Type .scopes (CLASS .decls => CLASS .decls1) :-
	TypeName.Declarations (.decls, .scopes) (.decls => .decls1) #
TypeName.Type .scopes
	(FUNC .parms .return .block => FUNC .parms1 .return1 .block1) :-
	TypeName.Declarations .scopes (.parms => .parms1),
	TypeName.Type .scopes (.return => .return1),
	TypeName.Statements .scopes (.block => .block1) #
TypeName.Type .scopes (TYPENAME .name => .real) :-
	list.member .scopes .scope,
	list.member .scope (TYPEDEF .type .name),
	TypeName.Type .scopes (.type => .real) ! #

TypeName.Statements .scopes (.stmt, .remains => .stmt1, .remains1) :-
	TypeName.Statement .scopes (.stmt => .stmt1),
	TypeName.Statements .scopes (.remains => .remains1) #
TypeName.Statements . ($ => $) #

TypeName.Statement .scopes (BLOCK .stmts => BLOCK .stmts1) :-
	TypeName.Statements .scopes (.stmts => .stmts1) #
TypeName.Statement .scopes (TYPEDEF .type .name => TYPEDEF .type1 .name) :-
	TypeName.Type .scopes (.type => .type1) #
TypeName.Statement .scopes (VARDEF .type .name => VARDEF .type1 .name) :-
	TypeName.Type .scopes (.type => .type1) #
TypeName.Statement .scopes (VARDEFVALUE .type .name .value =>
	VARDEFVALUE .type1 .name .value) :-
	TypeName.Type .scopes (.type => .type1) #
TypeName.Statement . (IF .cond .then => IF .cond .then) #
TypeName.Statement . (IFELSE .cond .then .else => IFELSE .cond .then .else) #
TypeName.Statement . (WHILE .cond .do => WHILE .cond .do) #
TypeName.Statement . (EXPR .expr => EXPR .expr) #


-- Type Handling --

Type.Size (INTTYPE .size) .ws :-
	Config.WordSize .ws, .size < .ws ! #
Type.Size (INTTYPE .size) .size #
Type.Size (PTR .) .size :-
	Config.PointerSize .size #
Type.Size (ARRAY .n .type) .s1 :-
	Type.Size .type .s0,
	let .s1 (.s0 * .n) #
Type.Size (FUNC . . .) 0 #
Type.Size (CLASS .members) .size :-
	Class.Size .members .size #

Class.Size (.vardef, .remains) .size :- (
		.vardef = VARDEF .type .;
		.vardef = VARDEFVALUE .type . .
	),
	Type.Size .type .size0,
	Class.Size .remains .size1,
	let .size (.size0 + .size1) #
Class.Size $ 0 #
